Python 标准库 -sys 模块
Python 标准库 -sys 模块
sys 模块提供了对解释器使用或维护的一些对象以及与解释器交互屏藩的函数的访问。
os、sys、platform 三个模块的区别:
os 提供操作系统的接口,常用的有文件系统相关和进程相关
sys 提供python 解释器系统的通用配置和函数,影响着解释器的行为(注意这里的系统不是操作系统,而是 python 解释器这个“系统”)
platform 提供平台相关的信息,比如硬件平台,软件平台
不知道为什么,Python 给我一种感觉,就是 Python 比 Java 更接近系统底层,不知道是不是因为 Python 比 Java 离 C 更近
模块内容
动态对象(动态变量):
-
argv:命令行参数列表,其中第一个参数,也就是 argv[0] 是当前通过
python /path2file/xxx.py
执行的脚本的路径,也就是/path2file/xxx.py
,可以是绝对路径也可以是相对路径 -
path:模块搜索路径列表,其中 path[0] 是当前指定的脚本所在的目录,可以是绝对路径,也可以用
''
空字符串表示搜索路径顺序如下:
-
当前指定的脚本所在的目录
-
当前工作目录(Working Directory)
-
PYTHONPATH
环境变量包含的目录,可能会有多个,sys.path
的一部分来自于PYTHONPATH
环境变量。 -
Pycharm 的 pycharm_display 包目录
-
Python安装目录\python310.zip
:zip 包默认不存在 -
Python安装目录\DLLs
:Windos 平台需要加载的 DLLs -
Python安装目录\lib
:官方包也成为标准库目录的所在目录 -
Python安装目录
(也就是说可以把模块放到这里) -
Python安装目录\lib\site-packages
:通过pip
下载的第三方的包保存在这里 -
Pycharm 的 pycharm_matplotlib_backend 包目录
site — Site-specific configuration hook — Python 3.10.12 documentation,这个方案我没实验成功,TODO
在程序运行的过程中可以动态添加路径到此变量中,然后通过
import
引入新路径中的模块。sys 影响着解释器的行为,因此动态添加了搜索路径之后,就能引导解释器的搜索行为,
如果我们有自定义添加搜索路径的需求,有两种方式:
-
sys.path.append(path)
手动添加 -
在
PYTHONPATH
中添加
类似于 Java 的类路径
-
-
modules:已加载模块的字典
-
displayhook:钩子对象,调用这个钩子以在交互式会话中显示结果
-
excepthook:钩子对象,调用来这个钩子处理除
SystemExit
之外的任何未捕获的异常 -
若要在交互式会话中自定义信息的打印或安装自定义顶级异常处理器,请分配其他函数来替换这两对象。
-
stdin:标准输入文件对象; 由 input() 方法使用
-
stdout:标准输出文件对象; 由 print() 使用
-
stderr:标准误差对象; 用于错误消息
-
通过分配其他文件对象 (或行为类似文件的对象) 给这三个对象,可以重定向解释器的所有 I/O。比如在 stdout,默认值是控制台输出,如果将其设置为一个 txt 文件对应的文件对象,那么从这个设置语句往后的所有输出都不会在控制台输出,而是会输出到文件中,设置语句往前的不会,所以这是一个动态切换的过程。
-
last_type:最近的一个未捕的获异常的类型
-
last_value:最近的一个未捕的获异常的值
-
last_traceback:对最近的一个未捕获异常的回溯(traceback)
-
这三个对象仅在打印 traceback 之后的交互式会话中可用。
静态对象(常量):
-
builtin_module_names:当前解释器内置的模块的名称的元组,通过这个元组我们可以快速判断某一个模块是不是内置模块
-
copyright:当前解释器的版权声明,是个写死的字符串
-
exec_prefix:前缀,用于查找特定于机器(machine-specific)的 Python 库,意思就是每台机器上,Python 都可能安装在不同的位置,其实就是 Python 的安装路径,比如我本机
D:\Python\Python3.10.4
-
prefix:用于查找 Python 库的前缀,跟
exec_prefix
基本相同 -
executable:Python 解释器的可执行二进制文件的绝对路径,一般都在
exec_prefix
表示的路径下 -
float_info:包含有关 float 实现的信息的元组。
-
float_repr_style:指示 repr() 对浮点数输出的样式的字符串
-
int_info:包含有关 int 实现信息的元组
-
hash_info:包含哈希算法信息的元组。
-
thread_info:一个带有线程实现信息的元组。返回
sys.thread_info(name='nt', lock=None, version=None)
-
hexversion:版本信息编码为单个整数。
-
implementation:当前使用的 Python 实现的信息,一般为
cpython
namespace(name='cpython', cache_tag='cpython-310', version=sys.version_info(major=3, minor=10, micro=4, releaselevel='final', serial=0), hexversion=50988272)
常见的 Python 实现有:
-
CPython:CPython 是用 C 语言实现 Pyhon,是目前应用最广泛的 Python 实现。Python 最新的语言特性都是在这个上面先实现,Linux,OS X 等自带的也是这个版本,包括 Anaconda 里面用的也是 CPython。CPython 是官方版本加上对于 C/Python API 的全面支持,基本包含了所有第三方库支持,例如 Numpy,Scipy 等。但是 CPython 有几个缺陷,一是全局锁使 Python 在多线程效能上表现不佳,二是 CPython 无法支持 JIT(即时编译),导致其执行速度不及 Java 和 Javascipt 等语言。于是出现了 Pypy
CPython 会将 Python 代码先编译为字节码,然后由其运行时解释执行。Python 的虚拟机叫 Python VM。跟 Java 虚拟机 JVM 是一个意思。但是 PVM 中不包含 JIT,这是 CPython 的 PVM 跟 JVM 的区别
-
Pypy:Pypy 是用 Python 自身实现的解释器。针对 CPython 的缺点进行了各方面的改良,性能得到很大的提升。最重要的一点就是 Pypy 集成了 JIT。但是,Pypy 无法支持官方的 C/Python API,导致无法使用例如 Numpy,Scipy 等重要的第三方库。这也是现在 Pypy 没有被广泛使用的原因吧。
-
Jython:Jython 是将 Python code 在 JVM 上面跑和调用 java code 的解释器。
其实基于我们在《基本概念》中学习的解释器和编译器的概念,可以确定,Python 规范的实现是包含了解释器的概念的。很多博客文章直接将 Python 的实现当作解释器,甚至在 Pycharm 中,我们在配置 Pycharm 的时候选择的核心配置叫 Interpreter,也不叫 Implementation,那里选了 CPython(名字上可能看不出来,从官网下载的包默认包就是 CPython),
sys.implementation
输出的就是 CPython,那里配置的是 Pypy 解释器,sys.implementation
输出的就是 Pypy,所以说,虽然说直接将实现跟解释器划等号是不准确的,但是大家都这么说,我们也没必要这么较真,心里明白即可。 -
-
maxsize:数据容器的最大支持长度。为
9223372036854775807
大概是 92 亿亿,就算一个元素一个字节,那也是非常大,大概 92 亿 G,可以说上限非常高了 -
maxunicode:Unicode 码点(code point)的最大值,
1114111
-
platform:平台标识符,输出的是
win32
,为什么系统明明是 64 位的,这里却返回 win32,实际上这个
win32
应该是指 Win32 API。如果你真的很在意架构,那可以用
platform
包import platform platform.machine()
输出 AMD64,与 Python 是不是 32 位没有关系
-
version:当前解释器的版本(返回为字符串)
3.10.4 (tags/v3.10.4:9d38120, Mar 23 2022, 23:13:41) [MSC v.1929 64 bit (AMD64)]
-
version_info:版本信息,以元组返回
sys.version_info(major=3, minor=10, micro=4, releaselevel='final', serial=0)
-
dllhandle:【仅限 Windows 系统】Python DLL 的整数 handle,
140720921116672
-
winver:【仅限 Windows 系统】Python DLL 的版本(数字),
3.10
-
_enablelegacywindowsfsencoding:启用经典的 windos 文件系统编码(我猜的)
-
__stdin__
:原始的 stdin,不要修改,对应动态对象 stdin -
__stdout__
:原始的 stdout,不要修改,对应动态对象 stdout -
__stderr__
:原始的 stderr,不要修改,对应动态对象 stderr -
__displayhook__
:原始的 displayhook,不要修改,对应动态对象 displayhook -
__excepthook__
:原始的 excepthook,不要修改,对应动态对象 excepthook
方法:
-
displayhook():将对象打印到屏幕上,并将其保存在
builtins._
中。注意,displayhook() 可调用多次,但是builtins._
中只会保存一个变量,即上一个在屏幕上输出的变量, -
excepthook():打印一个异常并将其回溯到 sys.stderr
-
exc_info():返回有关当前异常的线程安全信息
-
exit():通过抛出 SystemExit 来退出当前解释器的执行流程
-
getdlopenflags():返回用于 dlopen() 调用的标志
-
setdlopenflags():设置用于 dlopen() 调用的标志
-
getprofile():获取全局分析函数,如果没有通过 setprofile 设置,那没有
-
setprofile():设置全局分析函数
-
getrefcount():返回一个对象的引用计数,结果会比实际数量加一个,因为它包含 (临时) 引用作为 getrefcount() 的参数。
-
getrecursionlimit():返回解释器的最大递归深度,是
1000
,超过就会爆栈内存溢出的 bug,也就说递归调用不能超过 1000 次,一般也不会 -
setrecursionlimit():为解释器设置最大递归深度,最好不要乱设置,这个最大值是跟平台相关的。
-
gettrace():获取全局调试跟踪方法
-
settrace():设置全局调试跟踪方法
-
getsizeof():以字节为单位返回对象的大小
实践
简单实践如下:
import builtins
import sys
print("---------------------------------"+"sys.argv"+"---------------------------------")
for arg in sys.argv:
print(arg)
print("---------------------------------"+"sys.path"+"---------------------------------")
for path in sys.path:
print(path)
print("---------------------------------"+"sys.modules"+"---------------------------------")
for name,module in sys.modules.items():
print(name,"-",module)
# 重定向 stdout
# sys.stdout = open("./sys_out.txt","w",encoding="utf-8")
# 从这里开始,往后的所有输出都会输出到 sys_out.txt 文件中,而不是控制台中
# print("输出")
print("---------------------------------"+"sys.builtin_module_names"+"---------------------------------")
for module_name in sys.builtin_module_names:
print(module_name)
print("---------------------------------"+"sys.copyright"+"---------------------------------")
print(sys.copyright)
print("---------------------------------"+"sys.exec_prefix"+"---------------------------------")
print(sys.exec_prefix)
print("---------------------------------"+"sys.prefix"+"---------------------------------")
print(sys.prefix)
print("---------------------------------"+"sys.executable"+"---------------------------------")
print(sys.executable)
print("---------------------------------"+"sys.float_info"+"---------------------------------")
print(sys.float_info)
print("---------------------------------"+"sys.float_repr_style"+"---------------------------------")
print(sys.float_repr_style)
print("---------------------------------"+"sys.hexversion"+"---------------------------------")
print(sys.hexversion)
print("---------------------------------"+"sys.implementation"+"---------------------------------")
print(sys.implementation)
print("---------------------------------"+"sys.maxsize"+"---------------------------------")
print(sys.maxsize)
print("---------------------------------"+"sys.maxunicode"+"---------------------------------")
print(sys.maxunicode)
print("---------------------------------"+"sys.platform"+"---------------------------------")
print(sys.platform)
print("---------------------------------"+"sys.thread_info"+"---------------------------------")
print(sys.thread_info)
print("---------------------------------"+"sys.version"+"---------------------------------")
print(sys.version)
print("---------------------------------"+"sys.version_info"+"---------------------------------")
print(sys.version_info)
print("---------------------------------"+"sys.dllhandle"+"---------------------------------")
print(sys.dllhandle)
print("---------------------------------"+"sys.winver"+"---------------------------------")
print(sys.winver)
print("---------------------------------"+"sys.displayhook()"+"---------------------------------")
aa = "xiashuo.xyz"
sys.displayhook(12)
sys.displayhook(aa)
print(builtins._)
print("---------------------------------"+"sys.getprofile()"+"---------------------------------")
sys.getprofile()
print("---------------------------------"+"sys.getrefcount()"+"---------------------------------")
# 使用 sys.getrefcount() 方法来查看整数和字符串的引用次数结果会比较难以判定,因为Python对其有内存优化
print(sys.getrefcount(aa))
# 返回 3
print(sys.getrefcount(121545))
class Ref_test():
pass
# 正常,只会返回 1,也就是除了sys.getrefcount引用之外没有人引用
print(sys.getrefcount(Ref_test()))
print("---------------------------------"+"sys.getsizeof()"+"---------------------------------")
# 对象不包含任何内容,但是依然占据了内存
print(sys.getsizeof(Ref_test()))
print("---------------------------------"+"sys.getrecursionlimit()"+"---------------------------------")
print(sys.getrecursionlimit())
输出:
---------------------------------sys.argv---------------------------------
E:\PythonProject\PythonLearn\package_learn\built_in\sys_test.py
---------------------------------sys.path---------------------------------
E:\PythonProject\PythonLearn\package_learn\built_in
E:\PythonProject\PythonLearn
D:\Jetbrain_APP\apps\PyCharm-P\ch-0\231.9225.15\plugins\python\helpers\pycharm_display
D:\Python\Python3.10.4\python310.zip
D:\Python\Python3.10.4\DLLs
D:\Python\Python3.10.4\lib
D:\Python\Python3.10.4
D:\Python\Python3.10.4\lib\site-packages
D:\Jetbrain_APP\apps\PyCharm-P\ch-0\231.9225.15\plugins\python\helpers\pycharm_matplotlib_backend
---------------------------------sys.modules---------------------------------
sys - <module 'sys' (built-in)>
builtins - <module 'builtins' (built-in)>
_frozen_importlib - <module '_frozen_importlib' (frozen)>
_imp - <module '_imp' (built-in)>
_thread - <module '_thread' (built-in)>
_warnings - <module '_warnings' (built-in)>
_weakref - <module '_weakref' (built-in)>
_io - <module '_io' (built-in)>
marshal - <module 'marshal' (built-in)>
nt - <module 'nt' (built-in)>
winreg - <module 'winreg' (built-in)>
_frozen_importlib_external - <module '_frozen_importlib_external' (frozen)>
time - <module 'time' (built-in)>
zipimport - <module 'zipimport' (frozen)>
_codecs - <module '_codecs' (built-in)>
codecs - <module 'codecs' from 'D:\\Python\\Python3.10.4\\lib\\codecs.py'>
encodings.aliases - <module 'encodings.aliases' from 'D:\\Python\\Python3.10.4\\lib\\encodings\\aliases.py'>
encodings - <module 'encodings' from 'D:\\Python\\Python3.10.4\\lib\\encodings\\__init__.py'>
encodings.utf_8 - <module 'encodings.utf_8' from 'D:\\Python\\Python3.10.4\\lib\\encodings\\utf_8.py'>
_signal - <module '_signal' (built-in)>
_abc - <module '_abc' (built-in)>
abc - <module 'abc' from 'D:\\Python\\Python3.10.4\\lib\\abc.py'>
io - <module 'io' from 'D:\\Python\\Python3.10.4\\lib\\io.py'>
__main__ - <module '__main__' from 'E:\\PythonProject\\PythonLearn\\package_learn\\built_in\\sys_test.py'>
_stat - <module '_stat' (built-in)>
stat - <module 'stat' from 'D:\\Python\\Python3.10.4\\lib\\stat.py'>
_collections_abc - <module '_collections_abc' from 'D:\\Python\\Python3.10.4\\lib\\_collections_abc.py'>
genericpath - <module 'genericpath' from 'D:\\Python\\Python3.10.4\\lib\\genericpath.py'>
ntpath - <module 'ntpath' from 'D:\\Python\\Python3.10.4\\lib\\ntpath.py'>
os.path - <module 'ntpath' from 'D:\\Python\\Python3.10.4\\lib\\ntpath.py'>
os - <module 'os' from 'D:\\Python\\Python3.10.4\\lib\\os.py'>
_sitebuiltins - <module '_sitebuiltins' from 'D:\\Python\\Python3.10.4\\lib\\_sitebuiltins.py'>
_codecs_cn - <module '_codecs_cn' (built-in)>
_multibytecodec - <module '_multibytecodec' (built-in)>
encodings.gbk - <module 'encodings.gbk' from 'D:\\Python\\Python3.10.4\\lib\\encodings\\gbk.py'>
itertools - <module 'itertools' (built-in)>
keyword - <module 'keyword' from 'D:\\Python\\Python3.10.4\\lib\\keyword.py'>
_operator - <module '_operator' (built-in)>
operator - <module 'operator' from 'D:\\Python\\Python3.10.4\\lib\\operator.py'>
reprlib - <module 'reprlib' from 'D:\\Python\\Python3.10.4\\lib\\reprlib.py'>
_collections - <module '_collections' (built-in)>
collections - <module 'collections' from 'D:\\Python\\Python3.10.4\\lib\\collections\\__init__.py'>
types - <module 'types' from 'D:\\Python\\Python3.10.4\\lib\\types.py'>
_functools - <module '_functools' (built-in)>
functools - <module 'functools' from 'D:\\Python\\Python3.10.4\\lib\\functools.py'>
enum - <module 'enum' from 'D:\\Python\\Python3.10.4\\lib\\enum.py'>
_sre - <module '_sre' (built-in)>
sre_constants - <module 'sre_constants' from 'D:\\Python\\Python3.10.4\\lib\\sre_constants.py'>
sre_parse - <module 'sre_parse' from 'D:\\Python\\Python3.10.4\\lib\\sre_parse.py'>
sre_compile - <module 'sre_compile' from 'D:\\Python\\Python3.10.4\\lib\\sre_compile.py'>
_locale - <module '_locale' (built-in)>
copyreg - <module 'copyreg' from 'D:\\Python\\Python3.10.4\\lib\\copyreg.py'>
re - <module 're' from 'D:\\Python\\Python3.10.4\\lib\\re.py'>
token - <module 'token' from 'D:\\Python\\Python3.10.4\\lib\\token.py'>
tokenize - <module 'tokenize' from 'D:\\Python\\Python3.10.4\\lib\\tokenize.py'>
linecache - <module 'linecache' from 'D:\\Python\\Python3.10.4\\lib\\linecache.py'>
traceback - <module 'traceback' from 'D:\\Python\\Python3.10.4\\lib\\traceback.py'>
sitecustomize - <module 'sitecustomize' from 'D:\\Jetbrain_APP\\apps\\PyCharm-P\\ch-0\\231.9225.15\\plugins\\python\\helpers\\pycharm_matplotlib_backend\\sitecustomize.py'>
site - <module 'site' from 'D:\\Python\\Python3.10.4\\lib\\site.py'>
---------------------------------sys.builtin_module_names---------------------------------
_abc
_ast
_bisect
_blake2
_codecs
_codecs_cn
_codecs_hk
_codecs_iso2022
_codecs_jp
_codecs_kr
_codecs_tw
_collections
_contextvars
_csv
_datetime
_functools
_heapq
_imp
_io
_json
_locale
_lsprof
_md5
_multibytecodec
_opcode
_operator
_pickle
_random
_sha1
_sha256
_sha3
_sha512
_signal
_sre
_stat
_statistics
_string
_struct
_symtable
_thread
_tracemalloc
_warnings
_weakref
_winapi
_xxsubinterpreters
array
atexit
audioop
binascii
builtins
cmath
errno
faulthandler
gc
itertools
marshal
math
mmap
msvcrt
nt
sys
time
winreg
xxsubtype
zlib
---------------------------------sys.copyright---------------------------------
Copyright (c) 2001-2022 Python Software Foundation.
All Rights Reserved.
Copyright (c) 2000 BeOpen.com.
All Rights Reserved.
Copyright (c) 1995-2001 Corporation for National Research Initiatives.
All Rights Reserved.
Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
All Rights Reserved.
---------------------------------sys.exec_prefix---------------------------------
D:\Python\Python3.10.4
---------------------------------sys.prefix---------------------------------
D:\Python\Python3.10.4
---------------------------------sys.executable---------------------------------
D:\Python\Python3.10.4\python.exe
---------------------------------sys.float_info---------------------------------
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)
---------------------------------sys.float_repr_style---------------------------------
short
---------------------------------sys.hexversion---------------------------------
50988272
---------------------------------sys.implementation---------------------------------
namespace(name='cpython', cache_tag='cpython-310', version=sys.version_info(major=3, minor=10, micro=4, releaselevel='final', serial=0), hexversion=50988272)
---------------------------------sys.maxsize---------------------------------
9223372036854775807
---------------------------------sys.maxunicode---------------------------------
1114111
---------------------------------sys.platform---------------------------------
win32
---------------------------------sys.thread_info---------------------------------
sys.thread_info(name='nt', lock=None, version=None)
---------------------------------sys.version---------------------------------
3.10.4 (tags/v3.10.4:9d38120, Mar 23 2022, 23:13:41) [MSC v.1929 64 bit (AMD64)]
---------------------------------sys.version_info---------------------------------
sys.version_info(major=3, minor=10, micro=4, releaselevel='final', serial=0)
---------------------------------sys.dllhandle---------------------------------
140720921116672
---------------------------------sys.winver---------------------------------
3.10
---------------------------------sys.displayhook()---------------------------------
12
'xiashuo.xyz'
xiashuo.xyz
---------------------------------sys.getprofile()---------------------------------
---------------------------------sys.getrefcount()---------------------------------
5
3
1
---------------------------------sys.getsizeof()---------------------------------
48
---------------------------------sys.getrecursionlimit()---------------------------------
1000
动态修改 path 变量
- 直接修改 sys.path 列表
- 使用 PYTHONPATH 扩展
- 使用.pth 文件扩展,site — Site-specific configuration hook — Python 3.10.12 documentation,这个方案我没实验成功,TODO
动态添加 C:/Users/wwwli/Desktop/script
到 path 中,其中此路径下有文件 aaa.py
,内容如下:
abcd = "121312313"
class ABCD():
pass
执行测试脚本
print("---------------------------------dynamic sys.path---------------------------------")
# 动态添加 C:/Users/wwwli/Desktop/script 到 path
sys.path.append("C:/Users/wwwli/Desktop/script")
from aaa import abcd
from aaa import ABCD
print(abcd)
print(ABCD())
输出:
---------------------------------dynamic sys.path---------------------------------
121312313
<aaa.ABCD object at 0x0000026A31CA7E80>
注意,虽然解释器报错,但是执行是没有问题的
当然,如果路径真的不存在,那在执行的时候就会报错了。